#pragma once
template <typename E, int M>
struct SqStack
{
    E elem[M];
    int top;
};
template <typename E, int M>
void InitStack(SqStack<E,M> &S)
{
    S.top = 0;
}
template <typename E, int M>
bool StackEmpty(const SqStack<E,M> &S)
{
    return S.top == 0;
}
template <typename E, int M>
void Push(SqStack<E,M> &S, E e)
{
    if (S.top == M) throw "Stack full";
    S.elem[S.top++] = e;
}
template <typename E, int M>
void Pop(SqStack<E,M> &S, E &e)
{
    if (S.top == 0) throw "Stack empty";
    e = S.elem[--S.top];
}
template <typename E, int M>
void Pop(SqStack<E,M> &S)
{
    if (S.top == 0) throw "Stack empty";
    --S.top;
}
template <typename E, int M>
void GetTop(const SqStack<E,M> &S, E &e)
{
    if (S.top == 0) throw "Stack empty";
    e = S.elem[S.top - 1];
}
template <typename E, int M>
E GetTop(const SqStack<E,M> &S)
{
    if (S.top == 0) throw "Stack empty";
    return S.elem[S.top - 1];
}